home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
dskut
/
mindos11.zip
/
DEVINIT.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-22
|
10KB
|
290 lines
/* devinit.c -- Initialize disk device attributes */
/* Copyright 1991, Steven W. Harrold - All rights reserved */
/* $Header: DEVINIT.C_V 1.4 91/03/20 08:48:19 SWH Exp $ */
#include <stdlib.h>
#include <ctype.h>
#include <stddef.h>
#include "mfs.h"
#include "dev.h"
int Dstatus = 0 ; /* Status returned from last dev operation */
PRIVATE struct devdata *devinitf (int drive, int sides) ;
PRIVATE struct devdata *devinith (int drive) ;
/*================================================================*/
/* This routine determines the geometry of the disk in the specified
** physical drive.
**
** For floppy disks, the drives are identified by:
**
** 0x00 ===> the A: drive
** 0x01 ===> the B: drive, and so on.
**
** The physical attributes reported are a function both of the
** floppy drive AND the disk inserted in it.
**
** For hard disks, the PHYSICAL drives are identified by:
**
** 0x80 ===> physical hard disk 0
** 0x81 ===> physical hard disk 1, and so on.
**
** The routine IGNORES the logical partitioning of a hard disk drive,
** as it reports the attributes of the physical device. Make sure the
** drive identifier is NOT a function of its logical identity. In
** particular, C: usually corresponds to physical device 0x80, but
** if D: is a second partition on the disk, it will not correspond
** to physical 0x81.
*/
struct devdata *devinit (drive, sides)
int drive ; /* For floppies: 0 is A:, 1 is B:, etc */
/* Hard drives: 0x80 is PHYSICAL disk 0, 0x81 is 1 */
int sides ; /* 0 = determine actual value; non-0 = accept value */
/* Use 1 when 160KB disk has a formatted 2nd side */
{
if ((0xff & drive) >= 0x80)
return devinith (drive) ;
else
return devinitf (drive, sides) ;
} /* devinit() */
/*================================================================*/
/* This routine services only floppy disk drives. It determines,
** through trial and error, the geometry of the inserted disk.
** The actual type of drive is not determined.
**
** The possibilites recognized are:
**
** disk heads tracks sectors
** --------- ----- ------ -------
** 160 KB 5.25" 1 40 8 rare
** 320 KB 5.25" 2 40 8 less rare
** 360 KB 5.25" 2 40 9 DSSD
** 720 KB 5.25" 2 80 9 popular in Europe?
** 1.2 MB 5.25" 2 80 15 DSDD
** 720 KB 3.5" 2 80 9 low density
** 1.4 MB 3.5" 2 80 18 high density
*/
PRIVATE struct devdata *devinitf (drive, sides)
int drive ; /* For floppies: 0 is A:, 1 is B:, etc */
int sides ; /* 0 = determine actual value; non-0 = accept value */
/* Use 1 when 160KB disk has a formatted 2nd side */
{
struct devdata ddata, *dp ;
int head, track, sector ;
int done ;
char buffer[SECTOR_SIZE] ;
/* Establish an interim data block
*/
dp = &ddata ;
dp->d_drive = drive ;
/* Set the device addresses to minimum legal values. We operate with
** these small values because we have no assurance that a disk has been
** formatted to its capacity point. If the disk is only partially
** formatted, surely the first track, head and sector positions must
** be present.
*/
head = 0 ;
track = 0 ;
sector = 1 ;
/* The disk is accessed with various known max values looking for the
** fail points. The case of (status==NEW_MEDIA) indicates that the disk
** has been re-inserted while this test is underway, and so we have to
** start the determination all over again from the start.
*/
done = 0 ;
while (!done)
{
/* Reset the controller so that we have a known hardware state. If the
** floppy drive is not installed, the reset will fail.
*/
Dstatus = BIOSDISK(_DISK_RESET) ;
if (Dstatus == NEW_MEDIA) continue ;
if (Dstatus)
return NULL ;
/* Determine number of sectors accessible on the disk. A NO_SECTOR or a
** NO_MARKER status is expected if we reached too far. First sector is
** number 1. Note that we use max values for sector, but leave track
** and head at their minimum values.
*/
sector = 18 ; /* 1 of 4 possible values */
Dstatus = BIOSDISK(_DISK_VERIFY) ;
if (Dstatus) BIOSDISK(_DISK_RESET) ;
if (Dstatus == NEW_MEDIA) continue ;
if ((Dstatus == NO_MARKER) || (Dstatus == NO_SECTOR))
sector = 15 ; /* 2nd of 4 possibilities */
else if (Dstatus)
return NULL ;
if (sector == 15) /* True if previous attempt failed */
{
Dstatus = BIOSDISK(_DISK_VERIFY) ;
if (Dstatus) BIOSDISK(_DISK_RESET) ;
if (Dstatus == NEW_MEDIA) continue ;
if ((Dstatus == NO_MARKER) || (Dstatus == NO_SECTOR))
sector = 9 ; /* 3rd of 4 possibilities */
else if (Dstatus)
return NULL ;
}
if (sector == 9) /* True if previous attempt failed */
{
Dstatus = BIOSDISK(_DISK_VERIFY) ;
if (Dstatus) BIOSDISK(_DISK_RESET) ;
if (Dstatus == NEW_MEDIA) continue ;
if ((Dstatus == NO_MARKER) || (Dstatus == NO_SECTOR))
sector = 8 ; /* try the 4th possibility */
else if (Dstatus)
return NULL ;
}
if (sector == 8) /* True if previous attempt failed */
{
Dstatus = BIOSDISK(_DISK_VERIFY) ;
if (Dstatus) BIOSDISK(_DISK_RESET) ;
if (Dstatus == NEW_MEDIA) continue ;
if (Dstatus) /* it's probably unformatted */
return NULL ;
}
dp->d_sectors = sector ;
sector = 1 ; /* resume min value for next tests */
/* Determine number of heads accessible on the disk. Generally, there
** should always be two present, but a 160KB disk that is truly
** unformatted on the second side will show only 1. Heads start with
** number 0.
*/
if (sides == 0) /* test heads if no override supplied */
{
head = 1 ;
Dstatus = BIOSDISK(_DISK_VERIFY) ;
if (Dstatus) BIOSDISK(_DISK_RESET) ;
if (Dstatus == NEW_MEDIA) continue ;
if ((Dstatus == NO_MARKER) || (Dstatus == NO_SECTOR))
head = 0 ;
else if (Dstatus)
return NULL ;
}
else
head = sides - 1 ; /* assumes caller said 1 or 2 */
dp->d_heads = head + 1 ;
head = 0 ; /* resume min value */
/* Determine number of tracks accessible on the disk. A NO_MARKER
** status is expected if we attempted to reach too far. We try here
** to avoid seeking an excessive distance past a non-existent track
** as this causes the "grinding" noise we sometimes hear in a
** floppy drive. As the first track is number 0, a 40 track disk
** should fail with a track address of 40.
**
** It seems that some floppy disk drives can seek 1 extra cylinder,
** so, as an extra precaution, a failpoint of 41 is used rather than
** the theoretical 40. This should still avoid "head banging".
*/
track = 41 ; /* "one" past the 1st max value of 39 */
Dstatus = BIOSDISK(_DISK_VERIFY) ;
if (Dstatus) BIOSDISK(_DISK_RESET) ;
if (Dstatus == NEW_MEDIA) continue ;
if ((Dstatus == NO_MARKER) || (Dstatus == NO_SECTOR))
dp->d_tracks = 40 ; /* it is the first possibility */
else if (Dstatus)
return NULL ;
else
dp->d_tracks = 80 ; /* must be the other possibility */
/* When we get here, it means the disk/drive com